package com.joysuch.wwyt.attendant.job;


import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.joysuch.wwyt.attendant.entity.AttendantRecordProcess;
import com.joysuch.wwyt.attendant.service.AttendantRecordProcessService;
import com.joysuch.wwyt.bp.entity.InspectExceptionAlarmMesage;
import com.joysuch.wwyt.bp.service.InspectExceptionAlarmMesageService;
import com.joysuch.wwyt.config.RedisClient;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.enums.BaseConfigCodes;
import com.joysuch.wwyt.core.enums.DeleteFlag;
import com.joysuch.wwyt.core.repository.BaseConfigDao;
import jodd.util.StringPool;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RList;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.joysuch.wwyt.common.constant.Constant.*;

/**
 * @author xsx
 * @version 1.0
 * @date 2023/2/16 17:36
 */
@Slf4j
@AllArgsConstructor
@Component
public class ProcessStatusSyncJob {


    @Autowired
    private RedisClient redisClient;
    @Autowired
    private AttendantRecordProcessService attendantRecordProcessService;
    @Autowired
    private BaseConfigDao baseConfigDao;
    @Autowired
    private InspectExceptionAlarmMesageService inspectAlarmService;

    private static final String WORKFLOW_PROCESS_INS_QUEUE = "procDefKey:%s::%s";

    private static final String WORKFLOW_CACHE = "hse:workflow";
    private static final String WORKFLOW_PROCESS_INS = "procDefKey:%s::followerTaskSyncList";
    private static final String WORKFLOW_RISK_HD_INS = "risk.hidden.danger.process.key";


    private static final String INVES_TASK_TIME_OUT_ALARM = "invesTaskTimeOutAlarm";

    private static final String INSPECT_ALARM_REMARK = "流程业务";

    /**
     * 定时任务更新 关联隐患信息
     */
    @Scheduled(cron = "0 0/1 * * * ? ")
    public void ProcessStatusSyncJob() {
        BaseConfig ipConfig = baseConfigDao.findFirstByCodeNative(BaseConfigCodes.RISK_HIDDEN_DANGER_PROCESS_KEY);
        if (ipConfig != null) {
            String procDefKey = ipConfig.getValue();
            String key = WORKFLOW_CACHE.concat(StringPool.COLON).concat(StringPool.COLON).concat(String.format(WORKFLOW_PROCESS_INS, procDefKey));
            RList<String> list = redisClient.getList(key);
            if (list.isEmpty()) {
                return;
            }
            log.info(String.format("获取到redis流程状态数量" + list.size()));
            List<AttendantRecordProcess> processes = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                String processStr = list.get(i);
                AttendantRecordProcess process = JSONObject.parseObject(processStr, AttendantRecordProcess.class);
                AttendantRecordProcess recordProcess = attendantRecordProcessService.getAttendantRecordProcess(process.getDataSourceId(), process.getProcessInstanceId());
                if (recordProcess == null) {
                    BeanUtils.copyProperties(process, recordProcess);
                    recordProcess.setAttendantRecordId(recordProcess.getDataSourceId());
                } else {
                    if (!recordProcess.getProcessStatus().equals(process.getProcessStatus())) {
                        recordProcess.setProcessStatus(process.getProcessStatus());
                    }
                    if (recordProcess.getProcessCurTaskName() == null || !recordProcess.getProcessCurTaskName().equals(process.getProcessCurTaskName())) {
                        recordProcess.setProcessCurTaskName(process.getProcessCurTaskName());
                    }
                    if (recordProcess.getBusType() == null || !recordProcess.getBusType().equals(process.getBusType())) {
                        recordProcess.setBusType(process.getBusType());
                    }
                }
                processes.add(recordProcess);
            }
            if (!processes.isEmpty()) {
                log.info(String.format("更新流程状态表数量" + processes.size()));
                attendantRecordProcessService.saveOrUpdateBatch(processes);
            }
            redisClient.removeKey(key);
        }
    }

    /**
     * 定时任务更新巡检报警
     */
    @Scheduled(initialDelay = 10000, fixedDelay = 10 * 1000)
    public void ProcessInspectAlarmStatusSyncJob() {
        BaseConfig alarmonfig = baseConfigDao.findFirstByCodeNative(BaseConfigCodes.OPEN_HD_TIME_OUT_GRADE_ALARM);
        if (alarmonfig == null || StringUtils.isBlank(alarmonfig.getValue()) || !alarmonfig.getValue().equals(COMMON_SWITCH_ON)) {
            return;
        }
        BaseConfig defKeyConfig = baseConfigDao.findFirstByCodeNative(BaseConfigCodes.YH_TimeOut_ProcessDefKey);
        if (defKeyConfig == null || StringUtils.isBlank(defKeyConfig.getValue())) {
            return;
        }
        String procDefKey = defKeyConfig.getValue();
        String key = WORKFLOW_CACHE.concat(StringPool.COLON).concat(StringPool.COLON).concat(String.format(WORKFLOW_PROCESS_INS_QUEUE, procDefKey, INVES_TASK_TIME_OUT_ALARM));
        RList<String> list = redisClient.getList(key);
        if (list.isEmpty()) {
            return;
        }
        log.info(String.format("更新巡检报警数量,获取到redis流程状态数量===" + list.size()));
        List<Long> alarmIds = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            String processStr = list.get(i);
            ProcessStatusModel process = JSONUtil.toBean(processStr, ProcessStatusModel.class);
            if (StringUtils.isBlank(process.getDataSourceId())) {
                continue;
            }
            String processStatus = process.getProcessStatus();
            //保存结束 删除 作废的流程
            if (StringUtils.isNotBlank(processStatus) && (processStatus.equals(STATUS_FINISHED) || processStatus.equals(STATUS_TERMINATE) || processStatus.equals(STATUS_DELETE))) {
                alarmIds.add(Long.valueOf(process.getDataSourceId()));
            }
        }
        if (CollectionUtils.isEmpty(alarmIds)) {
            redisClient.removeKey(key);
            return;
        }
        List<InspectExceptionAlarmMesage> alarms = inspectAlarmService.list(new LambdaQueryWrapper<InspectExceptionAlarmMesage>().in(InspectExceptionAlarmMesage::getId, alarmIds).eq(InspectExceptionAlarmMesage::getDeleteFlag, DeleteFlag.EFFECTIVE.getCode()).eq(InspectExceptionAlarmMesage::getState, 0).isNotNull(InspectExceptionAlarmMesage::getProcInstId));
        log.info(String.format("更新巡检报警数量=====" + alarms.size()));
        if (CollectionUtils.isEmpty(alarms)) {
            redisClient.removeKey(key);
            return;
        }
        Date handleTime = new Date();
        for (InspectExceptionAlarmMesage alarm : alarms) {
            alarm.setState(1);
            alarm.setHandleTime(handleTime);
            alarm.setRemark(INSPECT_ALARM_REMARK);
        }
        inspectAlarmService.updateBatchById(alarms);
        redisClient.removeKey(key);

    }

}
